package iris_controller

import (
	"fmt"
	"github.com/kataras/iris/v12"
	"gluenet/internal/glue-srvp/domain"
	"gluenet/internal/glue-srvp/domain/vo"
	"gluenet/internal/pkg/infra"
	"gluenet/internal/pkg/infra/prepare"
)

func init() {
	prepare.RegisterAuthController(func() {
		controller := NewRepoController()
		prepare.InjectAuthController(func() *Repo {
			return controller
		})
	})
}

type Repo struct {
	Repo *domain.Repo
}

func NewRepoController() *Repo {
	r := &Repo{}
	prepare.FetchDependency(&r.Repo)
	return r
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/repo/all
func (c *Repo) GetAll(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	pageSize, err := ctx.URLParamInt64("page_size")
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	pageNumber, err := ctx.URLParamInt64("page_number")
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}

	var page vo.Page
	page.PageNumber = pageNumber
	page.PageSize = pageSize

	objs, err := c.Repo.FindBy(auth, &page, nil)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponsePageOK(page, objs)
}

// Get serves
// Method:   POST
// Resource: http://localhost:8080/apis/repo/query
func (c *Repo) PostQuery(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	pageSize, err := ctx.URLParamInt64("page_size")
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	pageNumber, err := ctx.URLParamInt64("page_number")
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	var page vo.Page
	page.PageNumber = pageNumber
	page.PageSize = pageSize

	var query = map[string]interface{}{}
	if err = ctx.ReadJSON(&query); err != nil {
		return infra.ResponseReqErr(err, nil)
	}

	objs, err := c.Repo.FindBy(auth, &page, query)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponsePageOK(page, objs)
}

// Create serves
// Method:   POST
// Resource: http://localhost:8080/apis/repo/create
func (c *Repo) PostCreate(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = []vo.CreateRepoReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read req %v", err), nil)
	}

	var res = make([]interface{}, len(req))
	for k, v := range req {
		repo, err := c.Repo.Create(auth, v)
		if err != nil {
			return infra.ResponseReqErr(fmt.Errorf("create file %v", err), nil)
		}
		res[k] = repo
	}
	return infra.ResponseOK(res)
}

// Create serves
// Method:   POST
// Resource: http://localhost:8080/apis/repo/update
func (c *Repo) PostUpdate(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.UpdateRepoReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read req %v", err), nil)
	}

	repo, err := c.Repo.Update(auth, req)
	if err != nil {
		return infra.ResponseReqErr(fmt.Errorf("update file %v", err), nil)
	}
	return infra.ResponseOK(repo)
}

// Create serves
// Method:   DELETE
// Resource: http://localhost:8080/apis/repo/delete
func (c *Repo) DeleteDelete(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.DeleteRepoReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read req %v", err), nil)
	}

	for _, id := range req.Ids {
		_, err := c.Repo.Delete(auth, id)
		if err != nil {
			return infra.ResponseReqErr(fmt.Errorf("delete repo %v", err), nil)
		}
	}
	return infra.ResponseOK(nil)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/repo/app/all
func (c *Repo) GetAppAll(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	repoId, err := ctx.URLParamInt64("id")
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}

	objs, err := c.Repo.ListRepoCharts(auth, repoId)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(objs)
}

// Get serves
// Method:   POST
// Resource: http://localhost:8080/apis/repo/helm/import
func (c *Repo) PostHelmImport(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.ImportRepoChartsReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read req %v", err), nil)
	}

	objs, err := c.Repo.ImportRepoChart(auth, req)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(objs)
}
